#include "ftpmanager.h"
#include <curl.h>
#include <QFile>
#include <QDebug>
#include <QtConcurrent>



// 全局静态变量存储上次进度，避免局部静态变量无法重置的问题
static qint64 s_lastPercent = -1; // 注意：全局作用域

// 进度回调函数
static int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
                             curl_off_t ultotal, curl_off_t ulnow) {
    // 重置逻辑：通过 clientp 为空触发（安全方式）
    if (!clientp) {
        s_lastPercent = -1; // 直接修改全局变量
        return 0;
    }

    QProgressBar* progressBar = static_cast<QProgressBar*>(clientp);
    if (ultotal <= 0 || !progressBar) return 0;

    qint64 percent = (ulnow * 100) / ultotal;
    percent = qMax(qMin(percent, 100LL), 0LL); // 使用 qBound 更简洁

    if (percent - s_lastPercent >= 1) {
        s_lastPercent = percent;
        qDebug() << "Progress:" << percent << "%";
        QMetaObject::invokeMethod(progressBar, "setValue", Qt::QueuedConnection,
                                  Q_ARG(int, static_cast<int>(percent)));
    }
    return 0;
}

// 重置进度回调静态变量（安全版本）
void resetProgressCallback() {
    progress_callback(nullptr, 0, 0, 0, 0); // 合法调用，触发重置分支
}

// 读取文件回调
static size_t read_callback(void* ptr, size_t size, size_t nmemb, void* userdata) {
    QFile* file = static_cast<QFile*>(userdata);
    return file->read(static_cast<char*>(ptr), size * nmemb);
}

FtpManager::FtpManager(QObject *parent) : QObject(parent) {
    m_watcher = new QFutureWatcher<bool>(this);
    connect(m_watcher, &QFutureWatcher<bool>::finished, this, &FtpManager::onUploadFinished);
}

FtpManager::~FtpManager() {
    if (m_watcher->isRunning()) {
        m_watcher->cancel();
        m_watcher->waitForFinished();
    }
}

void FtpManager::uploadFile(const QString& ftpServer, const QString& username, const QString& password,
                            const QString& localFilePath, const QString& remoteFilePath,
                            QProgressBar* progressBar) {
    // 重置进度回调静态变量
    resetProgressCallback();
    // 使用 Lambda 表达式在单独线程中执行上传
    QFuture<bool> future = QtConcurrent::run([=]() {
        CURL* curl = curl_easy_init();
        if (!curl) {
            m_errorMsg = "curl初始化失败";
            return false;
        }

        QString url = QString("ftp://%1:%2@%3/%4").arg(username).arg(password).arg(ftpServer).arg(remoteFilePath);
        curl_easy_setopt(curl, CURLOPT_URL, url.toUtf8().constData());
        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

        QFile localFile(localFilePath);
        if (!localFile.open(QIODevice::ReadOnly)) {
            m_errorMsg = QString("无法打开本地文件: %1").arg(localFilePath);
            curl_easy_cleanup(curl);
            return false;
        }

        qint64 fileSize = localFile.size();
        qDebug() << "Uploading file size:" << fileSize;  // 打印文件大小
        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, static_cast<curl_off_t>(fileSize));
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
        curl_easy_setopt(curl, CURLOPT_READDATA, &localFile);
        //curl_easy_setopt(curl, CURLOPT_FTPPUTASCII, 0L);

        // 启用进度回调
        if (progressBar) {
            curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
            curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
            curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progressBar);
        }

        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            m_errorMsg = QString("FTP上传失败: %1").arg(curl_easy_strerror(res));
            localFile.close();
            curl_easy_cleanup(curl);
            return false;
        }

        localFile.close();
        curl_easy_cleanup(curl);
        return true;
    });

    m_watcher->setFuture(future);
}

void FtpManager::onUploadFinished() {
    bool success = m_watcher->result();
    emit uploadFinished(success, m_errorMsg);
}
